package concurrentV;

import javax.swing.*;
import java.lang.invoke.VarHandle;

/**
 * 两个线程交替打印 1-100
 */
public class Thread1_100 {

    static class MyPrinter implements Runnable{

        private static Object lock = new Object();
        private static int count = 0; // 需要被打印的数字
        private boolean isEven;

        public MyPrinter(Boolean isEven){
            this.isEven = isEven;
        }

        @Override
        public void run() {
            while(count <= 100){
                synchronized (lock){
                    if((isEven && count % 2 != 0) || (!isEven && count % 2 != 1)){
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println(Thread.currentThread().getName() + ": "+ count);
                    count++;
                    lock.notifyAll();
                }
            }
        }
    }

    /**
     * 三个线程顺序打印1-100
     */
    static class MyPrinter2 implements Runnable {

        private final int rank; // 每个线程的固定身份
        private static final Object lock = new Object(); // 全局共享的锁
        private static int count = 1; // 要打印的数字，所有线程共享

        public MyPrinter2(int rank) {
            this.rank = rank;
        }

        @Override
        public void run() {
            while (true) {
                synchronized (lock) {
                    // 判断是否是当前线程需要打印的数字
                    while ((count - 1) % 3 != rank) {
                        if (count > 100) {
                            return; // 超过100时退出线程
                        }

                        try {
                            lock.wait(); // 当前线程等待
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }

                    // 如果数字在范围内，当前线程打印
                    if (count <= 100) {
                        System.out.println(Thread.currentThread().getName() + " -> " + count);
                        count++;
                        lock.notifyAll(); // 唤醒其他线程
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
//        new Thread(new MyPrinter(true), "EvenPrinter").start();
//        new Thread(new MyPrinter(false), "OddPrinter").start();

        MyPrinter2 myPrinter1 = new MyPrinter2(0);
        MyPrinter2 myPrinter2 = new MyPrinter2(1);
        MyPrinter2 myPrinter3 = new MyPrinter2(2);
        new Thread(myPrinter1).start();
        new Thread(myPrinter2).start();
        new Thread(myPrinter3).start();
    }
}
